<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>


<meta name="generator" content="Bluefish 1.0.7"><meta name="author" content="Carolina"><meta name="date" content="2008-03-17T21:10:31-0300"><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8"><style type="text/css">
pre {background: #eee; border: 1px dashed #889; margin-left: 3em; padding: 1ex;}
</style></head><body><div align="center"><h1>Laboratorio 1</h1>
<h2>Redes y Sistemas Distribuidos 2008</h2>
<h3>19 de Marzo de 2008</h3></div>








<br><br>

<h4>Objetivos</h4>
<ul>
<li> Hacer y entender cómo funciona un servidor de archivos.</li>
<li> Estudiar qué es un protocolo. Dado uno definido, aprender a implementarlo. </li>
<li> Aprender a usar las primitivas de sockets para hacer servidores.</li>
<li> Entender que las aplicaciones de redes pueden ser ejecutadas entre una máquina y otra sin importar que sistema
operativo posee cada una o el lenguaje de programación utilizado.</li>
</ul>

<br><br>

<h4>Motivación</h4>

<p>Los protocolos basados en el modelo cliente-servidor son muy comunes en
redes. Por lo general, el servidor acepta  conexiones simultáneas desde un gran
número de clientes (en ciertos casos el número máximo de peticiones
puede estar limitado). En este tipo de diseños, normalmente un servidor
inicia su tarea esperando por solicitudes de los clientes. Los clientes
realizan algún pedido al servidor, éste lo recibe, lo procesa, y envía
una respuesta al cliente.

</p><p>Esta comunicación entre servidor y cliente puede requerir muchos
mensajes entre ambos con el fin de procesar debidamente una
solicitud. La definición de cuáles son los mensajes que tanto el cliente
como el servidor entienden, e incluso la definición del orden de los
mismos, está dada por un <i>protocolo</i>.

</p><p>Un <b>protocolo</b> es un conjunto de reglas que define qué mensajes son
enviados entre los participantes (en este caso, cliente y servidor). Existen
muchos tipos de protocolos
en redes. Una de las partes usuales en un protocolo es el <i>handshaking</i>.
<b>Handshaking</b>, que en castellano significa estrechar las manos, es un
conjunto de pasos previos a la realización de un pedido por parte de los
clientes.

<br><br>

</p><h4>Tarea</h4>

<p>La aplicación a desarrollar en este laboratorio, consta de un programa
servidor y uno cliente, que se pueden ejecutar en el mismo o en
diferentes sistemas. El cliente será provisto por la cátedra, y uds
deberán implementar la parte del servidor.</p>

<p>Para ello, deberán:</p>
<ol>
	<li>Implementar el servidor en C.</li>
	<li>Modularizar adecuadamente el código que desarrollen.</li>
	<!--li>Definir un protocolo e implementarlo.</li-->
</ol>
<p>El servidor debe manejar una conexión por vez, y los clientes podrán realizar las siguientes solicitudes:
</p><ul>
	<li>Listar todos los archivos que se encuentren disponibles en el servidor.</li>
	<li>Dado un archivo existente en el servidor, obtener la metadata del mismo.
	    Para este laboratorio, la información proporcionada por el servidor será el tamaño del citado archivo.</li>
	<li>Dado un archivo existente en el servidor, obtener una fragmento del mismo.
	    Este fragmento estará dado por un <i>offset</i> y un tamaño	(offset es el comienzo de la porción deseada).
	</li>
	<li>Interrumpir la conexión</li>
</ul>	

<br><br>
<h4>Ejemplo</h4>
 
<p>A continuación daremos un ejemplo de la ejecución: </p>

<pre width="75">caro@victoria:~/Ayudantia/Redes08$python server.py
Running File Server on port 19500.
Connected by:  ('127.0.0.1', 44639)
Request: get_file_listing
Request: get_metadata client.py
Request: get_slice client.py 0 1868
Closing connection...
</pre>

<br><br>

<h4>Definición del protocolo HFTP</h4>

<p>El protocolo HFTP es un protocolo de capa de aplicación (ver sección 1.4
del libro de Tanenbaum par más detalles). Funciona usando como transporte
el protocolo TCP de internet.</p>

<p>El servidor debe escuchar permanentemente, atendiendo conexiones en el
puerto TCP 19500. Un cliente debe poder conectarse a este puerto y enviar
pedidos.</p>

<p>Todos los pedidos del cliente consisten en una cadena terminada en un
fín de línea estilo DOS ("\r\n"). Todo el tráfico del cliente al servidor
debe consistir de pedidos. Todo el tráfico del servidor a un cliente
se realiza en respuesta a un pedido.</p>

<p>El intercambio de mensajes es iniciado por el cliente. El servidor contesta
cada pedido antes de procesar/esperar el siguiente pedido. Esto se repite
intercaladamente, hasta que el cliente envía un pedido de fin de conexión.</p>

<p>El texto de un pedido está compuesto por elementos separados por
espacios o tabuladores. El caracter '\n' no puede aparecer en un pedido
excepto en el terminador '\r\n'. Si el servidor recibe un '\n' debería
devolver un código de error 100 (ver manejo de errores más abajo) e
interrumpir la conexión. El primer elemento del pedido es llamado el "comando",
y debe ser uno de los siguientes:</p>

<ul>
<li>get_file_listing</li>
<li>get_metadata</li>
<li>get_slice</li>
<li>quit</li>
</ul>

<p>Si el servidor recibe un pedido cuyo comando no es uno de los anteriores
debería devolver un código de error 200, y no realizar más acciones con el
pedido.</p>

<p>Cada uno de los elementos del pedido que no son el comando son llamados
"argumentos". Cada uno de los comandos anteriores acepta una cantidad fija de
argumentos (algunos comandos reciben 0 argumentos). Si el servidor recibe un
pedido con una cantidad incorrecta de argumentos para el comando solicitado,
debe contestar un código de error 201 y no seguir procesando el pedido.</p>

<p>Todas las respuestas del servidor al cliente comienzan con una cadena
terminada en <tt>\r\n</tt>, y pueden tener una continuación dependiendo el comando.
La cadena inicial siempre comienza con una secuencia de dígitos, seguida de
un espacio, seguido de un texto describiendo el resultado de la operación.
Este texto es a elección del implementador, pero debería ser descriptivo del
problema encontrado. Los valores numéricos posibles son:</p>

<table border="1">
    <tbody><tr><td>0</td><td>La operación se realizó con éxito.</td></tr>
    <tr><td>100</td><td>Se encontró un caracter <tt>\n</tt> fuera de un terminador de pedido <tt>\r\n</tt>.</td></tr>
    <tr><td>101</td><td>Alguna malformación del pedido impidió procesarlo.</td></tr>
    <tr><td>199</td><td>El servidor tuvo algún fallo interno al intentar procesar el pedido.</td></tr>
    <tr><td>200</td><td>El comando no está en la lista de comandos aceptados.</td></tr>
    <tr><td>201</td><td>La cantidad de argumentos no corresponde al comando, o los argumentos no tienen la forma correcta.</td></tr>
    <tr><td>202</td><td>El pedido se refiere a un archivo inexistente.</td></tr>
    <tr><td>203</td><td>El pedido se refiere a una posición inexistente en un archivo.</td></tr>
</tbody></table>

<p>Luego de enviar un código de error en el rango 100-199, el servidor
debería cerrar la conexión hacia el cliente (estos errores se consideran
"fatales"). El servidor sólo puede contestar 0 ante un pedido contestado
correctamente. Si el servidor contesta un valor distinto de 0, no
debería hacer modificaciones en su estado ni el del sistema más allá del
envío de mensaje de estado, y posible cierre de la conexión. Si el
servidor contesta un valor entre 200 y 299, la conexión debe permanecer
abierta y recibir pedidos posteriores.</p>

<h5>Descripción de cada comando</h5>

<p>El comando <code>get_file_listing</code> recibe 0 argumentos. Si
termina correctamente (con estado 0), luego de la línea de estado, se
envía una secuencia de líneas terminadas en <tt>\r\n</tt>, cada una con un nombre
de archivo disponible a través del servicio. Luego de esta secuencia de
líneas, sigue una línea sin más texto que el terminador <tt>\r\n</tt>, para
indicar el fin de la respuesta. </p>

<p>El comando <code>get_metadata</code> toma un argumento que debería ser
un nombre de archivo. Si este archivo no está disponible el servidor debería
retornar un error 202. Si está disponible, el servidor debe responder luego
de la línea de encabezado una línea terminada en <tt>\r\n</tt> con una secuencia de
dígitos indicando en base 10 la longitud del archivo.</p>

<p>El comando <code>get_slice</code> recibe tres argumentos. Los dos
últimos deben ser secuencia de dígitos (si no lo son el servidor debe
dar una respuesta 201). El primero debe indicar un archivo disponible
(de no serlo, corresponde una respuesta 202). Los dos argumentos
restantes son llamados el 'offset' y la 'longitud' respectivamente. Si
el 'offset' es mayor o igual a la longitud del archivo, o el 'offset'
sumado a la 'longitud' es mayor o igual a la longitud del archivo, el
servidor puede devolver un error 203.</p>

<p>Luego de la línea de encabezado, la respuesta al comando <code>get_slice</code>
esta formada por una secuencia de 1 o más fragmentos. Cada fragmento consiste en:</p>

<ol>
<li>Una secuencia de dígitos indicando en base 10 la longitud de la cadena de datos del fragmento, en bytes.</li>
<li>Un espacio en blanco</li>
<li>Una cadena de datos que debe ser exactamente de la cantidad de bytes indicada al principio del fragmento.</li>
<li>Un terminador <tt>\r\n</tt>
</li></ol>

<p>El último fragmento debe tener siempre longitud 0, y todos los
fragmentos anteriores deben tener tamaño positivo. Nótese que dentro de
la cadena de datos puede haber <tt>\r</tt> y/o <tt>\n</tt> intercalados, que no serán tomados
como delimitadores. La concatenación de las cadenas de datos contenidas en los fragmentos, en el orden que
son transmitidos, debería ser el contenido del archivo a partir de 'offset', y tener a lo sumo 'longitud' bytes.
El servidor debe intentar envíar 'longitud' bytes, a menos que encuentre que el archivo termina o se produzca
algún error de lectura.</p>

<p>El comando <code>quit</code> recibe 0 argumentos. La respuesta a este comando
debe ser siempre 0, y luego de enviarla debe cerrarse la conexión al cliente.</p>

<h4>Requisitos del código a entregar</h4>
<ul>
<li>La fecha de entrega es el jueves 3 de Abril, hasta las 23:59.</li>
<li>Se deberá enviar un archivo cuyo nombre sea <b>LabYGXX.tar.gz</b>
    donde <b>XX</b> es el número de grupo e <b>Y</b> es el numero de laboratorio.
	Por ejemplo, si el número de grupo es 1, el archivo que deberán enviar será: <b>Lab1G01.tar.gz</b></li>
<li>Junto con el código, se deberá entregar un informe en el cual se explique detalladamente
    la estructuración del servidor, las decisiones de diseño tomadas,
	dificultades con las que se encontraron, y cómo las resolvieron. 
El formato de dicho informe queda a elección de ustedes, siempre y cuando sea un formato libre.</li>
<li>Se deberá mantener un estilo de codificación uniforme.</li>
<li>También se exigirán las metodologías de programación defensiva y de buen manejo de memoria,
    aprendidas en materias anteriores.</li>
<li>El trabajo es grupal. Todos los integrantes del grupo deberán poder explicar el código presentado.</li>
<li>No está permitido compartir código entre grupos.</li>
</ul>

</body></html>